<template>
  <div id="app">
    <div class="todo-container">
      <div class="todo-wrap">
        <!-- 通过父组件传递函数，子组件通过props接收 进行通信 -->
        <!-- <TodoHeader :addTodo="addTodo"/>   -->
        <!-- 给list组件传入外部数据 -->
        <!-- <List :todos="todos" :handleCheck="handleCheck" :deleteTodo="deleteTodo"/>    中间表单组件 -->
        <!-- <TodoFooter :todos="todos" :checkAllTodo="checkAllTodo" :clearAllTodo="clearAllTodo"/>    底部组件 -->

        <!-- 通过父组件给子组件绑定自定义事件 进行通信 -->
        <TodoHeader @addTodo="addTodo"/>
        <List :todos="todos"/>
        <!-- <List :todos="todos" :handleCheck="handleCheck" :deleteTodo="deleteTodo"/>   -->
        <TodoFooter :todos="todos" @checkAllTodo="checkAllTodo" @clearAllTodo="clearAllTodo"/>    <!-- 底部组件 -->

      </div>
    </div>
  </div>
 
</template>

<script>
import TodoHeader from './components/TodoHeader.vue'
import List from './components/List.vue'
import TodoFooter from './components/TodoFooter.vue'

// 引入第三方库 消息订阅使用
import pubsub from 'pubsub-js'

export default {
  name: 'App',
  data(){
    return{
        // todos:[
        //     {id:'001',title:'学习',done:false},
        //     {id:'002',title:'看电影',done:false},
        //     {id:'003',title:'练车',done:true},
        // ]
        todos:[] || JSON.parse(localStorage.getItem('todo'))
    }
  },
  components: {
    TodoHeader,
    List,
    TodoFooter
  },
  methods: {
    // 添加数组对象，在头部组件调用到
    addTodo(todoObj){
      this.todos.unshift(todoObj)
    },
    // 修改数组对象里done属性的值、在list的item组件用到，所以需要层层传递
    handleCheck(id){
      this.todos.forEach((todos)=>{
        if(todos.id === id)
          todos.done = !todos.done
      })
    },
    // 删除对应数组内容 ，消息订阅的话是有两个参数，第一个使用不到，可以用下划线占位
    deleteTodo(_,id){
      this.todos = this.todos.filter((todo)=>{
        return todo.id !== id
      })
    },
     // 底部全选或取消全选
    checkAllTodo(done){
      this.todos.forEach((todo)=>{
        todo.done = done
      })
    },
    // 清除已完成的
    clearAllTodo(){
      this.todos = this.todos.filter((todo)=>{
        return !todo.done
      })
    },
    updateTodo(id,title){
      this.todos.forEach((todos)=>{
        if(todos.id === id)
          todos.title = title
      })
    }
  },
  // 监视数据todos数组的改变，然后向浏览器存储数据
  watch:{
    todos:{
      // 开启深度监视，这样数组里面的属性发生改变时候也能监视到
      deep:true,
      handler(value){
        // 第一个参数是监视到新数据
        // 将这个数据向本地浏览器存储
        // 注意存储的时候是字符串，而对象需要先通过JSON.stringify转换成字符串
        localStorage.setItem('todo',JSON.stringify(value))
      }
    }
  },

  // 接收数据
  mounted() {
    // 全局事件总线用法
    this.$bus.$on('handleCheck',this.handleCheck)
    
    // 消息订阅方法 
    this.pubId = pubsub.subscribe('deleTodo',this.deleteTodo)

    this.$bus.$on('updateTodo',this.updateTodo)
  },
  // 在销毁之前关闭自定义事件
  beforeDestroy(){
    this.$bus.$off('handleCheck')
    pubsub.unsubscribe(this.pubId)
    this.$bus.$off('updateTodo')
  }
 
}
</script>

<style>
  body{
    background: #fff;
  }
  .btn{
    display: inline-block;
    padding: 4px 12px;
    margin-bottom: 0;
    font-size: 14px;
    line-height: 20px;
    text-align: center;
    vertical-align: middle;
    cursor: pointer;   /* 设置光标移入时候显示的样子 pointer是一只手 */
    /* 内外阴影 */
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.5);
    border-radius: 4px;
    margin-right: 5px;
  }
  .btn:focus{
    /* 外边框 */
    outline: none;
  }
  /* 删除 */
  .btn-danger{
    color: #fff;
    background-color: #da4f49;
    border:1px solid #bd362f;
  }
  /* 编辑 */
  .btn-edit{
    color: #fff;
    background-color: #15a741;
    border:1px solid #0b7c24;
  }
  .btn-danger:hover{
    color:#fff;
    background-color: #bd362f;
  }
  .btn-edit:hover{
    color:#fff;
    background-color: #0b7c23;
  }
  .todo-container{
    width: 600px;
    margin: 0 auto;
  }
  .todo-container .todo-wrap{
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 5px;
  }
</style>
